package com.eaero.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eaero.CommonResp;
import com.eaero.entity.TraceTool;
import com.eaero.entity.TraceToolPick;
import com.eaero.entity.TraceToolPickDetail;
import com.eaero.entity.TraceUser;
import com.eaero.mapper.TraceToolPickMapper;
import com.eaero.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eaero.util.IdGenUtils;
import com.eaero.vo.*;
import com.eaero.vo.consts.Constants;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zb
 * @since 2023-03-14
 */
@Service
public class TraceToolPickServiceImpl extends ServiceImpl<TraceToolPickMapper, TraceToolPick> implements ITraceToolPickService {

    @Autowired
    private ITraceToolPickDetailService pickDetailService;

    @Autowired
    private ITraceToolService toolService;

    @Autowired
    private ITraceWorkOrderDetailService traceWorkOrderDetailService;

    @Autowired
    private ITraceUserService traceUserService;

    @Override
    public CommonResp getToolPickHD(String tpNo, String createdUser, String createdDate, String status, String updatedUsers) {
        //List<TraceToolPick> list = list(Wrappers.<TraceToolPick>lambdaQuery()
        //        .select(TraceToolPick::getTpNo,
        //                TraceToolPick::getCreatedUser,
        //                TraceToolPick::getCreatedDate,
        //                TraceToolPick::getStatus,
        //                TraceToolPick::getUpdatedUser,
        //                TraceToolPick::getUpdatedDate,
        //                TraceToolPick::getReqNo)
        //        .eq(StrUtil.isNotEmpty(tpNo), TraceToolPick::getTpNo, tpNo)
        //        .eq(StrUtil.isNotEmpty(createdUser), TraceToolPick::getCreatedUser, createdUser)
        //        .eq(StrUtil.isNotEmpty(createdDate), TraceToolPick::getCreatedDate, createdDate)
        //        .eq(StrUtil.isNotEmpty(status), TraceToolPick::getStatus, status)
        //        .like(StrUtil.isNotEmpty(updatedUsers), TraceToolPick::getUpdatedUser, updatedUsers)
        //);

        List<TraceToolPick> toolPickHD = getBaseMapper().getToolPickHD(tpNo, createdUser, createdDate, status, updatedUsers);
        if (CollUtil.isEmpty(toolPickHD)) {
            return CommonResp.buildFailMsg("没有数据");
        }
        return CommonResp.buildSucsDataListMsg(toolPickHD, "数据获取成功！");
    }

    @Override
    public CommonResp cancelToolPickHD(CancelToolPickRequest request) {
        List<CancelToolPick> cancelPick = request.getCancelPick();
        List<String> tpNos = cancelPick.stream().map(CancelToolPick::getTpNo).collect(Collectors.toList());
        long count = count(Wrappers.<TraceToolPick>lambdaQuery()
                .in(TraceToolPick::getTpNo, tpNos)
                .in(TraceToolPick::getStatus, "D", "U").last("limit 1"));

        if (count > 0) {
            return CommonResp.buildFailMsg("只有开放状态的捡料单可以进行作废");
        }

        long checkFlag = count(Wrappers.<TraceToolPick>lambdaQuery()
                .in(TraceToolPick::getTpNo, tpNos)
                .eq(TraceToolPick::getStatus, "N"));
        if (checkFlag != tpNos.size()) {
            return CommonResp.buildFailMsg("没有该拣料单");
        }

        update(Wrappers.<TraceToolPick>lambdaUpdate().set(TraceToolPick::getStatus, "D").in(TraceToolPick::getTpNo, tpNos));
        return CommonResp.buildSucsDataListMsg(null, "作废拣料单成功！");
    }

    @Override
    public CommonResp getToolPickdetail(String tpId, String tpNo) {
        List<TraceToolPickDetail> traceToolPickDetails = pickDetailService.list(Wrappers.<TraceToolPickDetail>lambdaQuery()
                .select(TraceToolPickDetail.class, info -> !"state".equals(info.getColumn()))
                .eq(StrUtil.isNotEmpty(tpId), TraceToolPickDetail::getTpId, tpId)
                .eq(StrUtil.isNotEmpty(tpNo), TraceToolPickDetail::getTpNo, tpNo)
                .eq(TraceToolPickDetail::getState, Constants.STATE.NORMAL));

        if (CollUtil.isNotEmpty(traceToolPickDetails)) {
            return CommonResp.buildSucsDataListMsg(traceToolPickDetails, "数据获取成功！");
        } else {
            return CommonResp.buildFailMsg("没有数据");
        }
    }

    @Override
    public CommonResp deleteToolPickDetail(DeleteToolPickDetailRequest request) {
        List<DeleteToolPickDetail> deletePickdetail = request.getDeletePickdetail();
        List<String> tpdIds = deletePickdetail.stream().map(DeleteToolPickDetail::getTpdId).collect(Collectors.toList());

        List<TraceToolPickDetail> toolPickDetails = pickDetailService.list(Wrappers.<TraceToolPickDetail>lambdaQuery()
                .in(TraceToolPickDetail::getTpdId, tpdIds));

        if (CollUtil.isEmpty(toolPickDetails)) {
            return CommonResp.buildFailMsg("没有该拣料单明细");
        }
        List<String> tpIds = toolPickDetails.stream().map(TraceToolPickDetail::getTpId).collect(Collectors.toList());

        long count = count(Wrappers.<TraceToolPick>lambdaQuery()
                .in(TraceToolPick::getId, tpIds)
                .in(TraceToolPick::getStatus, "D", "U").last("limit 1"));

        if (count > 0) {
            return CommonResp.buildFailMsg("仅开放状态的拣料单可以删除拣料单明细");
        }

        pickDetailService.update(Wrappers.<TraceToolPickDetail>lambdaUpdate()
                .set(TraceToolPickDetail::getState, Constants.STATE.DELETE)
                .in(TraceToolPickDetail::getTpdId, tpdIds));
        return CommonResp.buildSucsDataListMsg(null, "删除拣料明细成功！");
    }

    @Override
    public CommonResp updateToolPickdetailPn(UpdateToolPickdetailPnRequest request) {
        List<UpdateToolPickdetailPn> updatePickdetail = request.getUpdatePickdetail();
        List<String> tpdIds = updatePickdetail.stream().map(UpdateToolPickdetailPn::getTpdId).collect(Collectors.toList());

        List<TraceToolPickDetail> toolPickDetails = pickDetailService.list(Wrappers.<TraceToolPickDetail>lambdaQuery()
                .in(TraceToolPickDetail::getTpdId, tpdIds));

        if (CollUtil.isEmpty(toolPickDetails)) {
            return CommonResp.buildFailMsg("没有该拣料单明细");
        }

        List<String> tpIds = toolPickDetails.stream().map(TraceToolPickDetail::getTpId).collect(Collectors.toList());

        long count = count(Wrappers.<TraceToolPick>lambdaQuery()
                .in(TraceToolPick::getId, tpIds)
                .in(TraceToolPick::getStatus, "D", "U").last("limit 1"));

        if (count > 0) {
            return CommonResp.buildFailMsg("仅开放状态的拣料单可以删除拣料单明细");
        }

        // 检查件号是否存在
        //List<String> pns = updatePickdetail.stream().map(UpdateToolPickdetailPn::getPn).collect(Collectors.toList());
        //long pnCount = toolService.count(Wrappers.<TraceTool>lambdaQuery().in(TraceTool::getPartno, pns));
        //if (pnCount != pns.size()) {
        //    return CommonResp.buildFailMsg("更改的件号不存在");
        //}

        for (UpdateToolPickdetailPn updateToolPickdetailPn : updatePickdetail) {
            pickDetailService.update(Wrappers.<TraceToolPickDetail>lambdaUpdate()
                    .set(TraceToolPickDetail::getPartno, updateToolPickdetailPn.getPn())
                    .eq(TraceToolPickDetail::getTpdId, updateToolPickdetailPn.getTpdId()));
        }

        return CommonResp.buildSucsDataListMsg(null, "更新件号成功！");
    }

    @Override
    public CommonResp updateToolPickdetailList(UpdateToolPickdetailListRequest request) {
        List<UpdateToolPickdetailList> updatePickdetail = request.getUpdatePickdetail();
        List<String> tpdIds = updatePickdetail.stream().map(UpdateToolPickdetailList::getTpdId).collect(Collectors.toList());

        List<TraceToolPickDetail> toolPickDetails = pickDetailService.list(Wrappers.<TraceToolPickDetail>lambdaQuery()
                .in(TraceToolPickDetail::getTpdId, tpdIds));

        if (CollUtil.isEmpty(toolPickDetails)) {
            return CommonResp.buildFailMsg("没有该拣料单明细");
        }

        List<String> tpIds = toolPickDetails.stream().map(TraceToolPickDetail::getTpId).collect(Collectors.toList());

        long count = count(Wrappers.<TraceToolPick>lambdaQuery()
                .in(TraceToolPick::getId, tpIds)
                .in(TraceToolPick::getStatus, "D", "U").last("limit 1"));

        if (count > 0) {
            return CommonResp.buildFailMsg("仅开放状态的拣料单可以删除拣料单明细");
        }

        for (UpdateToolPickdetailList updateToolPickdetailList : updatePickdetail) {
            pickDetailService.update(Wrappers.<TraceToolPickDetail>lambdaUpdate()
                    .set(TraceToolPickDetail::getSeriano, updateToolPickdetailList.getSerialno())
                    .eq(TraceToolPickDetail::getTpdId, updateToolPickdetailList.getTpdId()));
        }
        return CommonResp.buildSucsDataListMsg(null, "指定建议批号成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CommonResp goPickTools(PickToolsRequest request) {
        CommonResp resp = CommonResp.buildFailMsg("生成拣料单失败！");
        TraceToolPick traceToolPick = new TraceToolPick();
        List<TraceToolPickDetail> traceToolPickDetails = new ArrayList<>();
        List<String> rids = request.getNewPick().stream().map(PickToolsDetail::getRid).collect(Collectors.toList());
        List<WorkOrderDetail> workOrderDetails = traceWorkOrderDetailService.getWorkOrderDetailByRid(rids);
        //Map<String, List<WorkOrderDetail>> wordOrderGroup = workOrderDetails.stream().collect(Collectors.groupingBy(item -> StrUtil.format("{}#{}#{}#{}", item.getTailNo(), item.getRcvBy(), item.getPickDate(), item.getWhsType())));
        //if (NumberUtil.compare(wordOrderGroup.keySet().size(), 1) != 0) {
        //    return CommonResp.buildFailMsg("飞机号、收货人、工作日期、拣料仓库需一致才能生成拣料单");
        //}
        List<String> partnos = workOrderDetails.stream().map(WorkOrderDetail::getPn).collect(Collectors.toList());
        List<TraceTool> tools = toolService.list(Wrappers.<TraceTool>lambdaQuery()
                .in(TraceTool::getPartno, partnos)
        );
        Map<String, List<TraceTool>> partnoGroup = tools.stream().collect(Collectors.groupingBy(TraceTool::getPartno));
        TraceUser traceUser = traceUserService.getOne(Wrappers.<TraceUser>lambdaQuery()
                .in(TraceUser::getUserCode, request.getUserCode())
        );
        String tpNo = StrUtil.format("JLD{}", RandomStringUtils.randomNumeric(6));
        Iterator<WorkOrderDetail> iterator = workOrderDetails.iterator();
        while (iterator.hasNext()) {
            WorkOrderDetail workOrderDetail = iterator.next();
            List<TraceTool> traceTools = partnoGroup.get(workOrderDetail.getPn());
            if (CollUtil.isEmpty(traceTools)) {
                return CommonResp.buildFailMsg(StrUtil.format("{}件号在所选仓库中没有库存", workOrderDetail.getPn()));
            }
            if (StrUtil.isEmpty(traceToolPick.getId())) {
                // 拣料单
                traceToolPick.setId(IdGenUtils.genId());
                traceToolPick.setTpNo(tpNo);
                traceToolPick.setCreatedUser(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
                traceToolPick.setCreatedDate(request.getUserCode());
                traceToolPick.setStatus("N");
                traceToolPick.setUpdatedUser(null);
                traceToolPick.setUpdatedDate(null);
                traceToolPick.setReqNo(workOrderDetail.getReqNo());
                traceToolPick.setReqUser(StrUtil.format("{} {}", traceUser.getUserCode(), traceUser.getComMobile()));
                traceToolPick.setTailNo(workOrderDetail.getTailNo());
                traceToolPick.setVisitDesc(workOrderDetail.getVisitDesc());
                traceToolPick.setCreateTime(LocalDateTime.now());
                traceToolPick.setModifyTime(LocalDateTime.now());
            }
            // 拣料单详情
            TraceTool traceTool = traceTools.get(0);
            TraceToolPickDetail detail = new TraceToolPickDetail();
            detail.setId(IdGenUtils.genId());
            detail.setAlternatePartno(workOrderDetail.getPn());
            detail.setCreatedDate(DateUtil.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm:ss"));
            detail.setCreatedUser(request.getUserCode());
            detail.setDescription(traceTool.getWhseDesc());
            detail.setIssueNum(workOrderDetail.getQty());
            detail.setIssueRid(workOrderDetail.getRid());
            detail.setJcSeq(workOrderDetail.getJcSeq());
            detail.setOnhand(traceTool.getOnhand());
            detail.setParentId("");
            detail.setPartdescr(workOrderDetail.getPartdescr());
            detail.setPartno(workOrderDetail.getPn());
            detail.setQty(workOrderDetail.getQty());
            detail.setRcvBy(workOrderDetail.getRcvBy());
            detail.setSeriano("");
            detail.setSotrsloc(traceTool.getStoresloc());
            detail.setTailNo(workOrderDetail.getTailNo());
            detail.setTdRid(workOrderDetail.getRid());
            detail.setTpId(IdGenUtils.genId());
            detail.setTpNo(tpNo);
            detail.setTpdId(IdGenUtils.genId());
            detail.setTpdlId("");
            detail.setUnitofmeas(traceTool.getUnitofmeas());
            detail.setUpdatedDate(null);
            detail.setUpdatedUser(null);
            detail.setVisitDesc(workOrderDetail.getVisitDesc());
            detail.setWarehouse(traceTool.getWarehouse());
            detail.setWorkorder(workOrderDetail.getJcWorkorder());
            detail.setDetailPartno(workOrderDetail.getPn());
            detail.setMeasuringNo("");
            detail.setReqNo(workOrderDetail.getReqNo());
            detail.setTpdlRemark("");
            detail.setOpSeq(StrUtil.format("LSH{}", RandomStringUtils.randomNumeric(6)));
            detail.setImgFlag("N");
            detail.setRfidId(traceTool.getRfidId());
            detail.setState("0");
            traceToolPickDetails.add(detail);
        }

        Boolean flag = this.save(traceToolPick);
        Boolean detailFlag = pickDetailService.saveBatch(traceToolPickDetails);
        if (flag && detailFlag) {
            resp = CommonResp.buildSuccessMsg(StrUtil.format("生成拣料单成功！[{}]", tpNo));
        }
        return resp;
    }

    @Override
    public CommonResp deleteToolPickDetailList(DeleteToolPickDetailListRequest request) {
        List<DeleteToolPickDetailList> deleteToolPickDetailList = request.getDeleteToolPickDetailList();
        List<String> tpdlIds = deleteToolPickDetailList.stream().map(DeleteToolPickDetailList::getTpdlId).collect(Collectors.toList());

        for (String tpdlId : tpdlIds) {
            pickDetailService.update(Wrappers.<TraceToolPickDetail>lambdaUpdate()
                    .set(TraceToolPickDetail::getTpdlId, StrUtil.EMPTY)
                    .eq(TraceToolPickDetail::getTpdlId, tpdlId));
        }
        return CommonResp.buildSuccessMsg("删除建议批号成功！");
    }
}
